package evaluation;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

public class Evaluater {
	private Vector<ReasonPair> extractedPairVector = new Vector<ReasonPair>();
	private Vector<ReasonPair> groundtruthPairVector = new Vector<ReasonPair>();
	public void ReadExtractedPairs(String rootDir)
	{
		this.extractedPairVector.clear();
		File root = new File(rootDir);
		if(!root.exists()||!root.isDirectory()) 
		{
			System.out.println("Wrong Extracted Dir!");
			return;
		}
		File[] files = root.listFiles();
		for(File file : files)
		{
			if(file.getName().startsWith(".")) continue;
			try {
				BufferedReader freader = new BufferedReader(new FileReader(file.getAbsolutePath()));
				String line;
				while((line=freader.readLine())!=null)
				{
					if(line.length()>0&&!line.contains("Duration="))
					{
						ReasonPair pair = new ReasonPair();
						pair.ReadExtractedLine(line);
						this.extractedPairVector.add(pair);
					}
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	public void ReadGroundTruthPairs(String rootDir)
	{
		this.groundtruthPairVector.clear();
		File root = new File(rootDir);
		if(!root.exists()||!root.isDirectory()) 
		{
			System.out.println("Wrong Ground Truth Dir!");
			return;
		}
		File[] files = root.listFiles();
		for(File file : files)
		{
			if(file.getName().startsWith(".")) continue;
			try {
				BufferedReader freader = new BufferedReader(new FileReader(file.getAbsolutePath()));
				String line;
				while((line=freader.readLine())!=null)
				{
					if(line.length()>0&&!line.contains("r=\"nm\"")&&!line.contains("ln=\"list\""))
					{
						ReasonPair pair = new ReasonPair();
						pair.ReadGrountTruthLine(line,file.getName());
						this.groundtruthPairVector.add(pair);
					}
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public void ReadNoDeepParsePairs(String rootDir)
	{
		this.extractedPairVector.clear();
		File root = new File(rootDir);
		if(!root.exists()||!root.isDirectory()) 
		{
			System.out.println("Wrong No Deep Parse Dir!");
			return;
		}
		File[] files = root.listFiles();
		for(File file : files)
		{
			if(file.getName().startsWith(".")) continue;
			try {
				BufferedReader freader = new BufferedReader(new FileReader(file.getAbsolutePath()));
				String line;
				while((line=freader.readLine())!=null)
				{
					if(line.length()>0&&!line.contains("r=\"nm\"")&&!line.contains("ln=\"list\""))
					{
						ReasonPair pair = new ReasonPair();
						pair.ReadGrountTruthLine(line,file.getName());
						this.extractedPairVector.add(pair);
					}
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public void evaluatePairs()
	{
		int correctNum = 0;
		try {
			BufferedWriter fwriter = new BufferedWriter(new FileWriter("output/evaluation/FalsePositive.txt"));
			BufferedWriter TPfwriter = new BufferedWriter(new FileWriter("output/evaluation/TruePositive.txt"));
			for(ReasonPair extractedPair : this.extractedPairVector)
			{
				boolean truePositive = false;
				for(ReasonPair groundtruthPair : this.groundtruthPairVector)
				{
					if(extractedPair.equals(groundtruthPair)) 
					{
						correctNum++;
						truePositive = true;
						break;
					}
				}
				if(!truePositive)
				{
					fwriter.write(extractedPair.toString());
					fwriter.newLine();
				}else{
					TPfwriter.write(extractedPair.toString());
					TPfwriter.newLine();
				}
			}
			fwriter.close();
			TPfwriter.close();
			double precision = (double)correctNum / (double)extractedPairVector.size();
			
			fwriter = new BufferedWriter(new FileWriter("output/evaluation/FalseNegetive.txt"));
			correctNum=0;
			for(ReasonPair groundtruthPair : this.groundtruthPairVector)
			{
				boolean truePositive = false;
				for(ReasonPair extractedPair : this.extractedPairVector)
				{
					if(extractedPair.equals(groundtruthPair)) 
					{
						correctNum++;
						truePositive = true;
						break;
					}
				}
				if(!truePositive)
				{
					fwriter.write(groundtruthPair.toString());
					fwriter.newLine();
				}
			}
			fwriter.close();
			double recall = (double)correctNum / (double)groundtruthPairVector.size();
			double fscore = 2*precision*recall/(precision+recall);
			System.out.println("Evaluation of pairs:"+"Precision="+precision+" recall="+recall+" fscore="+fscore);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}
	public void evaluateTokens()
	{
		Vector<String> extractedTokenVector = new Vector<String>();
		for(ReasonPair extractedPair : this.extractedPairVector)
		{
			String[] tokens = extractedPair.getReason().split("\\s+");
			for(String token : tokens)
			{
				token = token.trim();
				token = token.toLowerCase();
				token = token.replaceAll("\\.", "");
				if(token.length()>1&&!extractedTokenVector.contains(token)) extractedTokenVector.add(token);
			}
		}
		Vector<String> goldTokenVector = new Vector<String>();
		for(ReasonPair groundtruthPair : this.groundtruthPairVector)
		{
			String[] tokens = groundtruthPair.getReason().split("\\s+");
			for(String token : tokens)
			{
				token = token.trim();
				token = token.toLowerCase();
				token = token.replaceAll("\\.", "");
				if(token.length()>1&&!goldTokenVector.contains(token)) goldTokenVector.add(token);
			}
		}
		int correctNum=0;
		for(String extractedToken : extractedTokenVector)
			for(String goldToken : goldTokenVector)
			{
				if(extractedToken.equals(goldToken)) correctNum++;
			}
		double precision = (double)correctNum / (double)extractedTokenVector.size();
		double recall = (double)correctNum / (double)goldTokenVector.size();
		double fscore = 2*precision*recall/(precision+recall);
		System.out.println("Evaluation of tokens:"+"Precision="+precision+" recall="+recall+" fscore="+fscore);
	}
}
